﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Unity;
using System.ComponentModel;
using System.Collections.ObjectModel;
using XbdSoft.Domain;
using XbdSoft.Contract;
using XbdSoft.Client;
using System.Windows.Input;
using Microsoft.Practices.Composite.Presentation.Commands;
using System.Windows.Media;
using System.Net;
using XbdSoft.WPFVersion.Common;
using System.Threading;

namespace XbdSoft.WPFVersion.ViewModel
{
    public class RecommendDownloadViewModel : INotifyPropertyChanged
    {
        #region Fields
        protected readonly IEventAggregator EventAggregator = null;
        protected readonly IUnityContainer Container = null;
        #endregion

        #region Media Player
        protected MediaPlayer mediaPlayer = null;
        #endregion

        #region Ctor

        public RecommendDownloadViewModel(IEventAggregator eventAggregator, IUnityContainer container)
        {
            EventAggregator = eventAggregator;
            Container = container;
            Initialize();
            mediaPlayer = new MediaPlayer();
            TryListenCommand = new DelegateCommand<object>(OnTryListen, o => true);
            DownloadAllSelectedResourceCommand = new DelegateCommand<object>(OnDownloadAllSelectedResource, o => true);
            SelectAllResourceCommand = new DelegateCommand<object>(OnSelectAllResource, o => true);
            SelectOthersResourceCommand = new DelegateCommand<object>(OnSelectOthersResource, o => true);
            RefreshResourceCommand = new DelegateCommand<object>(OnRefreshResourceCommand);
        }

        #endregion

        #region Initialize
        protected void Initialize()
        {
            //Refresh();
            //selectedCategoryIndex = -1;
            //selectedResourceIndex = -1;
        }
        #endregion

        #region INotifyPropertyChanged Members

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Properties
        private ObservableCollection<AudioCategory> recommendCategories = new ObservableCollection<AudioCategory>();
        public ObservableCollection<AudioCategory> RecommendCategories
        {
            get { return recommendCategories; }
            set
            {
                recommendCategories = value;
                OnPropertyChanged("RecommendCategories");
            }
        }
        private ObservableCollection<AudioResource> recommendResources = new ObservableCollection<AudioResource>();
        public ObservableCollection<AudioResource> RecommendResources
        {
            get { return recommendResources; }
            set
            {
                recommendResources = value;
                OnPropertyChanged("RecommendResources");
            }
        }

        private int selectedCategoryIndex = -1;
        public int SelectedCategoryIndex 
        {
            get { return selectedCategoryIndex; }
            set
            {
                if (selectedCategoryIndex != value)
                {
                    selectedCategoryIndex = value;
                    OnPropertyChanged("SelectedCategoryIndex");
                    OnPropertyChanged("SelectedCategory");
                    SelectedResourceIndex = SelectedCategory.AudioResources.Count > 0 ? 0 : -1;
                }
            }
        }

        public AudioCategory SelectedCategory
        {
            get 
            {
                if (recommendCategories.Count > 0 && selectedCategoryIndex >= 0 && selectedCategoryIndex < recommendCategories.Count)
                    return recommendCategories[selectedCategoryIndex];
                return new AudioCategory();
            }
        }

        private int selectedResourceIndex = -1;
        public int SelectedResourceIndex
        {
            get { return selectedResourceIndex; }
            set
            {
                if (selectedResourceIndex != value)
                {
                    selectedResourceIndex = value;
                    OnPropertyChanged("SelectedResourceIndex");
                    OnPropertyChanged("SelectedResource");
                }
            }
        }

        public AudioResource SelectedResource
        {
            get
            {
                if (SelectedCategory != null && SelectedCategory.AudioResources.Count > 0 && selectedResourceIndex >= 0 && SelectedCategory.AudioResources.Count > selectedResourceIndex)
                    return SelectedCategory.AudioResources[selectedResourceIndex];
                return new AudioResource();
            }
        }
                
        #endregion

        #region Extenal Call
        public void Refresh()
        {
            RefreshRecommends();
            SelectedCategoryIndex = 0;
            SelectedResourceIndex = 0;
        }

        public void RefreshRecommends()
        {
            var recmmds = new List<AudioCategory>();
            using (var downloadService = new ServiceObject<IDownloadService>(Util.DownloadServiceAddress))
            {
                recmmds = downloadService.Object.GetRecommendDownloadCategories();
            }
            RecommendCategories = new ObservableCollection<AudioCategory>(recmmds);
            var recmmdResources = recmmds.Aggregate(new List<AudioResource>(), (current, category) =>
            {
                return current.Concat(category.AudioResources).ToList();
            });
            RecommendResources = new ObservableCollection<AudioResource>(recmmdResources);
        }
        #endregion

        #region Commands
        public ICommand TryListenCommand { get; set; }
        protected virtual void OnTryListen(object args)
        {
            var id = (int)args;
            try
            {
                var resource = SelectedCategory.AudioResources.SingleOrDefault(r => r.ID == id);
                if (resource != null)
                {
                    var index = SelectedCategory.AudioResources.IndexOf(resource);
                    SelectedResourceIndex = index;
                    //var url = string.Empty;
                    //using (var service = new ServiceObject<IDownloadService>(Util.DownloadServiceAddress))
                    //{
                    //    url = service.Object.GetDownloadUrl(id);
                    //}
                    //mediaPlayer.Close();
                    //mediaPlayer.Open(new Uri(url));
                    //mediaPlayer.Play();
                    EventAggregator.GetEvent<TryListenEvent>().Publish(new TryListenEventArgs() { ResourceID = id });
                }
            }
            catch
            {
                //mediaPlayer.Close();
            }
        }

        public ICommand DownloadAllSelectedResourceCommand { get; set; }
        protected virtual void OnDownloadAllSelectedResource(object args)
        {
            foreach (var resouce in SelectedCategory.AudioResources)
            {
                if (resouce.Selected)
                {
                    var eventArgs = new DownloadResourceEventArgs() { Resource = resouce };
                    EventAggregator.GetEvent<DownloadResourceEvent>().Publish(eventArgs);
                    //Thread.Sleep(500);
                }
            }
        }

        public ICommand SelectAllResourceCommand { get; set; }
        protected virtual void OnSelectAllResource(object args)
        {
            var isChecked = (bool)args;
            foreach (var resouce in SelectedCategory.AudioResources)
            {
                resouce.Selected = isChecked;
            }
            OnPropertyChanged("SelectedCategory");
        }

        public ICommand SelectOthersResourceCommand { get; set; }
        protected virtual void OnSelectOthersResource(object args)
        {
            foreach (var resouce in SelectedCategory.AudioResources)
            {
                resouce.Selected = !resouce.Selected;
            }
            OnPropertyChanged("SelectedCategory");
        }

        public ICommand RefreshResourceCommand { get; set; }
        protected virtual void OnRefreshResourceCommand(object args)
        {
            Refresh();
        }
        #endregion
    }
}
